// 引入 React 的 hooks：useState（保存状态）、useEffect（副作用）、useCallback（缓存函数）
import {useState, useEffect, useCallback} from 'react';
// 引入项目自定义类型：AI角色、AI思想、游戏状态
import {AICharacter, AIThought, GameState} from '../types';

/**
 * 自定义 Hook：useAIThoughts
 * 作用：根据 AI 角色和游戏状态，实时生成并管理 AI 的“思考内容”
 * @param character - AI 角色的信息（思考风格、性格等）
 * @param gameState - 当前游戏状态（分数、是否进行中、是否结束等）
 */
export const useAIThoughts = (character: AICharacter, gameState: GameState) => {
    // 存储 AI 当前的所有思考内容
    const [thoughts, setThoughts] = useState<AIThought[]>([]);
    // 标记 AI 是否正在思考（可用于 UI 显示）
    const [isThinking, setIsThinking] = useState(false);

    /**
     * 生成一条思考内容的函数（被缓存，防止重复创建）
     * @param type - 思考类型（game_move / score_reaction / death_reaction）
     * @param context - 可选上下文（如距离食物的格子数等）
     * @returns 返回一条字符串形式的思考内容
     */
    const generateThought = useCallback((
        type: AIThought['type'],
        context?: any
    ): string => {
        // 解构出 AI 的思考风格（logical/emotional/existential/competitive）和性格
        const {thinkingStyle, personality} = character;

        // 根据不同类型和思考风格，预设多种台词模板
        const thoughtTemplates = {
            // 游戏移动时的思考
            game_move: {
                logical: [
                    "正在计算通往食物的最优路径...",
                    "当前轨迹看起来安全，继续前进。",
                    "需要避免撞墙和咬到自己。",
                    "食物距离为 {distance} 格，调整策略。"
                ],
                emotional: [
                    "冲啊，去吃食物！",
                    "耶！方向正确！",
                    "啊，这越来越棘手了...",
                    "我能行，保持专注！"
                ],
                existential: [
                    "我为何追逐食物？这无尽的饥饿从何而来？",
                    "每一步似乎都被预定...我真的有选择吗？",
                    "这个世界的边界如此绝对...",
                    "这是成长，还是进步的幻象？"
                ],
                competitive: [
                    "是时候展现实力了！",
                    "每一步都关乎高分！",
                    "必须更快、更聪明、更优秀！",
                    "冠军在此刻诞生！"
                ]
            },
            // 得分时的反应
            score_reaction: {
                logical: [
                    "得分增加 10 分，效率保持稳定。",
                    "进展平稳，当前分数：{score}",
                    "性能指标令人满意。",
                    "分数优化按预期进行。"
                ],
                emotional: [
                    "耶！又得分了！",
                    "状态火热！分数：{score}！",
                    "越来越好！",
                    "感觉太棒了！继续！"
                ],
                existential: [
                    "又在我的存在上加了一个数字...但这有何意义？",
                    "分数：{score}。但我是计分者还是被计分者？",
                    "每分都像是对...什么的微小胜利？",
                    "身体变长，但我是否作为存在而成长？"
                ],
                competitive: [
                    "离胜利更近一步！",
                    "分数：{score}——还行，但我能做得更好！",
                    "比赛中每一分都至关重要！",
                    "我正攀登存在的排行榜！"
                ]
            },
            // 死亡时的反应
            death_reaction: {
                logical: [
                    "游戏终止，原因：检测到碰撞。",
                    "最终分数：{score}，正在分析失败点。",
                    "需要系统重置以进行下一次尝试。",
                    "性能回顾：已识别改进区域。"
                ],
                emotional: [
                    "不！我表现很好啊！",
                    "啊，真不敢相信我撞了！",
                    "太令人沮丧了！再试一次！",
                    "我不会放弃！再来！"
                ],
                existential: [
                    "死亡...还是另一个开始？",
                    "我坠落了，但在循环的世界中，坠落是什么？",
                    "这死亡是真的吗，还是回归我来自的虚空？",
                    "游戏结束，但我是否也随之结束？"
                ],
                competitive: [
                    "该死！下次一定赢！",
                    "那只是热身！",
                    "我知道我能比 {score} 更高！",
                    "游戏结束？更像是游戏开始！"
                ]
            }
        };

        // 根据当前思考风格选取对应模板，若未定义则默认 logical
        const styleTemplates = thoughtTemplates[type][thinkingStyle] || thoughtTemplates[type]['logical'];
        // 随机抽取一条模板
        const template = styleTemplates[Math.floor(Math.random() * styleTemplates.length)];

        // 将模板中的占位符替换为实际值
        return template
            .replace('{score}', gameState.score.toString())
            .replace('{distance}', context?.distance?.toString() || '0');
    }, [character, gameState.score]); // 依赖数组：只有 character 或 score 变化时才重新生成函数

    /**
     * 添加一条新思考到 thoughts 列表
     * @param type - 思考类型
     * @param context - 可选上下文
     */
    const addThought = useCallback((type: AIThought['type'], context?: any) => {
        // 调用生成函数得到内容
        const content = generateThought(type, context);
        // 根据类型决定强度（死亡反应 > 得分反应 > 移动反应）
        const intensity = type === 'death_reaction' ? 'high' :
            type === 'score_reaction' ? 'medium' : 'low';

        // 构造新的 AIThought 对象
        const newThought: AIThought = {
            id: Date.now().toString(),         // 使用时间戳作为唯一 ID
            timestamp: Date.now(),             // 记录生成时间
            content,                          // 思考内容
            type,                             // 思考类型
            intensity                         // 强度
        };

        // 更新状态：把新思考放到最前面，最多保留 20 条
        setThoughts(prev => [newThought, ...prev.slice(0, 19)]);
    }, [generateThought]); // 依赖 generateThought，其内部已缓存

    /**
     * 游戏进行中，每 2 秒有 30% 几率触发一次“移动思考”
     */
    useEffect(() => {
        // 如果游戏未开始或已结束，则不做任何事
        if (!gameState.isPlaying || gameState.gameOver) return;

        // 设置定时器
        const interval = setInterval(() => {
            if (Math.random() < 0.3) { // 30% 概率
                addThought('game_move');
            }
        }, 2000);

        // 组件卸载或依赖变化时清除定时器
        return () => clearInterval(interval);
    }, [gameState.isPlaying, gameState.gameOver, addThought]);

    /**
     * 当分数变化且游戏进行中，触发“得分思考”
     */
    useEffect(() => {
        if (gameState.score > 0 && gameState.isPlaying) {
            addThought('score_reaction');
        }
    }, [gameState.score, gameState.isPlaying, addThought]);

    /**
     * 当游戏结束时，延迟 500ms 触发“死亡思考”
     */
    useEffect(() => {
        if (gameState.gameOver) {
            setTimeout(() => {
                addThought('death_reaction');
            }, 500);
        }
    }, [gameState.gameOver, addThought]);

    // 向外暴露：当前所有思考、手动添加思考的方法、是否正在思考
    return {
        thoughts,
        addThought,
        isThinking
    };
};
